﻿using Uniforax.Core.Common;
using Uniforax.Core.GameObjects;

namespace Uniforax.Core.GameActions
{
    public class MoveGameObjectAction : BaseGameAction
    {
        public PosId StartPosId { get; set; }
        public string ObjectId { get; set; }
        public WayPoints WayPoints { get; set; }

        public MoveGameObjectAction(BaseGameObject gameObject, WayPoints wayPoints)
        {
            StartPosId = gameObject.PosId;
            ObjectId = gameObject.ObjectId;
            WayPoints = wayPoints;
        }

        public override void Execute(ActionContext context)
        {
            var world = context.GameWorld;
            var lastPoint = StartPosId;
            var objectId = ObjectId;

            foreach (var wayPoint in WayPoints)
            {
                var nextEnterPoint = wayPoint;
                var grid1 = world.GetGrid(lastPoint);

                var gameObject = grid1.GetPlacedObject(objectId);
                if (gameObject is null)
                {
                    throw new NullReferenceException($"MoveGameObjectAction.Execute: 无法在 {grid1} 找到 Id 为 {objectId} 的对象。");
                }

                var leaveContext = new GameObjectLeaveGridMovementContext()
                {
                    GameObject = gameObject,
                    OldGrid = grid1,
                };

                grid1.RemovePlacedObject(gameObject);
                grid1.OnGameObjectLeave(context, leaveContext);
                gameObject.OnLeaveGrid(context, leaveContext);

                var grid2 = world.GetGrid(nextEnterPoint);

                var enterContext = new GameObjectEnterGridMovementContext()
                {
                    GameObject = gameObject,
                    NewGrid = grid2,
                };

                grid2.OnGameObjectEnter(context, enterContext);
                gameObject.OnEnterGrid(context, enterContext);

                var placeContext = new GameObjectPlaceGridMovementContext()
                {
                    GameObject = gameObject,
                    CurrentGrid = grid2,
                };

                grid2.PlaceObject(gameObject);
                grid2.OnGameObjectPlaced(context, placeContext);
                gameObject.OnPlacedGrid(context, placeContext);

                lastPoint = nextEnterPoint;
            }
        }

        public override void Undo(ActionContext context)
        {
            //var gameObject = context.GameWorld.GetGameObject(PosId, ObjectId);
        }

    }
}
